﻿// 文件使用MiniExcel源码， 使用时需遵循其 Apache License 2.0
// 修改摘要通知： 删除异步、Task等net2.0中不支持的内容，替换原先C#自带的zip处理方式，改用yacomp 进行解压缩。
using System;
using System.IO;
using System.Text;
using System.Xml;
using yacomp.os;

namespace ExcelConfig.Zip
{
    /// Copy & modified by ExcelDataReader ZipWorker @MIT License
    internal class ExcelOpenXmlZip : IDisposable
    {
        private bool _disposed;
        internal MiniExcelZipArchive zipFile;
        public YacompStorage storage;

        private static readonly XmlReaderSettings XmlSettings = new XmlReaderSettings
        {
            IgnoreComments = true,
            IgnoreWhitespace = true,
            XmlResolver = null,
        };
        public ExcelOpenXmlZip(Stream fileStream, bool leaveOpen = false, Encoding entryNameEncoding = null,bool isUpdateMode=true)
        {
            zipFile = new MiniExcelZipArchive(fileStream, leaveOpen, entryNameEncoding);
            if (isUpdateMode)
            {
                try
                {
                    storage = zipFile.zip.GetStorage(); //TODO:need to remove
                }
                catch (InvalidDataException e)
                {
                    throw new InvalidDataException($"It's not legal excel zip, please check or issue for me. {e.Message}");
                }
            }
        }
        public YacompFile CreateEntry(string path)
        {
            return storage.OperateFile(path);
        }
        public XmlReader GetXmlReader(string path)
        {
            if (storage.Exist(path)) return XmlReader.Create(storage.FindFile(path).ToStream(), XmlSettings);
            return null;
        }

        ~ExcelOpenXmlZip()
        {
            Dispose(false);
        }

        public void Dispose()
        {
            Dispose(true);
            if (zipFile != null)
            {
                zipFile.Dispose();
                zipFile = null;
            }
            GC.SuppressFinalize(this);
        }

        private void Dispose(bool disposing)
        {
            // Check to see if Dispose has already been called.
            if (!_disposed)
            {
                if (disposing)
                {
                    if (zipFile != null)
                    {
                        zipFile.Dispose();
                        zipFile = null;
                    }
                }

                _disposed = true;
            }
        }
    }
}
